package page

import (
	"net/http"
	"net/url"

	"gitee.com/haodreams/golib/easyroute/group"
	"gitee.com/haodreams/golib/minauth"
	"gitee.com/haodreams/golib/session"
	"github.com/gin-gonic/gin"
	"github.com/mojocn/base64Captcha"
)

type Auther interface {
	GetUser(username string) session.Userer
	FindBySID(sid string) (sess session.Sessioner, err error)
}
type Login struct {
	group.Group
	auth          Auther
	verifyCaptcha func(id, code string) bool // 验证码校验函数
}

func NewLogin(auth Auther) *Login {
	m := new(Login)
	m.auth = auth
	return m
}

// SetVerifyCaptcha 设置验证码校验函数
func (m *Login) SetVerifyCaptcha(f func(id, code string) bool) *Login {
	m.verifyCaptcha = f
	return m
}

func (m *Login) Login(c *gin.Context) {
	param := m.Params(c).Form(c.Request)
	username := param.GetTrimString("username")
	password := param.GetTrimString("password")
	if m.verifyCaptcha != nil {
		id := param.GetTrimString("cid")
		if id == "" {
			m.Msg(c, "无效的验证码ID", http.StatusUnauthorized)
			return
		}
		code := param.GetTrimString("captcha")
		if code == "" {
			m.Msg(c, "无效的验证码", http.StatusUnauthorized)
			return
		}
		if !m.verifyCaptcha(id, code) {
			m.Msg(c, "验证码错误", http.StatusUnauthorized)
			return
		}
	}

	if username == "" {
		m.Msg(c, "无效的用户名", http.StatusUnauthorized)
		return
	}

	if password == "" {
		m.Msg(c, "无效的密码", http.StatusUnauthorized)
		return
	}

	user := m.auth.GetUser(username)
	if user == nil {
		m.Msg(c, "无效的用户名或密码", http.StatusUnauthorized)
		return
	}

	if user.GetName() == username && user.GetPassword() == password {
		clientIP := c.ClientIP()
		sess := minauth.Register(username, "", "", clientIP)
		m.SetCookie(c, "uid", sess.SID, 3600*24*7)
		if user.GetHome() != "" {
			//c.Redirect(http.StatusFound, user.GetHome())
			m.Data(c, user.GetHome(), "登录成功", http.StatusFound)
			return
		}
		m.Data(c, "登录成功")
		return
	}
	m.Msg(c, "用户名或密码不正确", http.StatusUnauthorized)
}

// Logout ...
func (m *Login) Logout(c *gin.Context) {
	uid, err := c.Cookie("uid")
	if err != nil {
		m.Msg(c, "成功退出", http.StatusOK)
		//m.Redirect(302, "/go/login/login")
		return
	}

	minauth.RemoveBySID(uid)
	m.SetCookie(c, "uid", "", -1)
	m.Msg(c, "成功退出")
	//m.Redirect(301, "/go/login/login")
}

// Modify 修改密码
func (m *Login) Modify(c *gin.Context) {
	if m.IsPost(c) {
		pwd := ""
		newpwd := ""
		contentType := c.ContentType()
		if contentType == "application/json" {
			type User struct {
				Pwd    string `json:"pwd"`
				NewPwd string `json:"newpwd"`
			}
			var u User
			err := c.ShouldBindJSON(&u)
			if err != nil {
				m.Msg(c, err.Error(), http.StatusBadRequest)
				return
			}
			pwd = u.Pwd
			newpwd = u.NewPwd
			pwd = minauth.Hash(pwd)
			newpwd = minauth.Hash(newpwd)
		} else {
			param := m.Params(c).Form(c.Request)
			pwd = param.GetTrimString("pwd")
			newpwd = param.GetTrimString("newpwd")
		}

		username := ""
		var err error

		uid := c.Request.Header.Get("Authorization")
		if uid == "" {
			//step1 : 检查cookie中是否带有参数
			uid, err = c.Cookie("uid")
			if err != nil || uid == "" {
				//step2 : 检查参数中是否带有uid
				vals, _ := url.ParseQuery(c.Request.URL.RawQuery)
				uids := vals["uid"]
				if len(uids) > 0 {
					uid = uids[0]
				} else {
					m.Msg(c, "登录已经过期,请重新登录", http.StatusUnauthorized)
					return
				}
			}
		}

		sess, err := minauth.FindBySID(uid)
		if err != nil || sess == nil {
			m.Msg(c, "登录已经过期,请重新登录", http.StatusUnauthorized)
			return
		}
		username = sess.Name

		user := minauth.GetUsers().GetUser(username)
		if user == nil {
			m.Msg(c, "登录已经过期,请重新登录", http.StatusUnauthorized)
			return
		}

		if user.GetPassword() != pwd {
			m.Msg(c, "当前密码错误", http.StatusUnauthorized)
			return
		}

		user.SetPassword(newpwd)
		err = minauth.Save()
		if err != nil {
			user.SetPassword(pwd)
			m.Msg(c, "密码更新失败", http.StatusInternalServerError)
			return
		}

		m.Msg(c, "密码修改成功")
		return
	}
}

// Delete 删除用户
func (m *Login) Delete() {
}

// Status 登录状态
func (m *Login) Status(c *gin.Context) {
	uid, err := c.Cookie("uid")
	if err != nil {
		m.Msg(c, "需要重新登录", http.StatusUnauthorized)
		return
	}

	ses, err := m.auth.FindBySID(uid)
	if err != nil || ses == nil {
		m.Msg(c, "登录已经过期，需要重新登录", http.StatusUnauthorized)
		return
	}
	m.Msg(c, "OK")
}

var store = base64Captcha.DefaultMemStore

// 生成验证码
func GenerateCaptcha(c *gin.Context) {
	// 配置验证码参数（宽度、高度、长度等）
	driver := base64Captcha.NewDriverDigit(80, 240, 4, 0.7, 80)
	captcha := base64Captcha.NewCaptcha(driver, store)

	// 生成验证码ID和图片base64
	id, b64s, _, err := captcha.Generate()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  "生成验证码失败",
		})
		return
	}

	// 返回验证码ID和图片给前端
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "success",
		"data": gin.H{
			"captchaId":   id,   // 验证码ID（用于后续验证）
			"imageBase64": b64s, // 验证码图片base64（前端可直接渲染）
		},
	})
}

// 验证验证码
func VerifyCaptcha(id, code string) bool {
	// 验证验证码（store.Verify会自动删除已验证的验证码，防止重复使用）
	return store.Verify(id, code, true)
}
